package com.example.demo.mapper;

import com.baomidou.mybatisplus.annotation.TableId;
import org.apache.ibatis.annotations.*;

import java.lang.reflect.Field;
import java.util.Random;

public interface CommonMapper<T> {
    @Select(" select nextVal(${tableSeqName})")
    String getNextVal(String tableSeqName);

    @InsertProvider(type = SqlProvider.class, method = "insert")
    int insert(T entity);

    @UpdateProvider(type = SqlProvider.class, method = "update")
    int update(T entity);

    @DeleteProvider(type = SqlProvider.class, method = "deleteById")
    int deleteById(T entity);

    @SelectProvider(type = SqlProvider.class, method = "getById")
    T getById(T entity);
    @SelectProvider(type = SqlProvider.class, method = "getById2")
    T getById2(T entity);
//
//    @SelectProvider(type = SqlProvider.class, method = "getAll")
//    List<T> getAll();

    class SqlProvider<T> {
        public String insert(T entity) {
            Class<?> clazz = entity.getClass();
            StringBuilder sql = new StringBuilder();
            sql.append("INSERT INTO ").append(getTableName(clazz)).append(" (");

            Field[] fields = clazz.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                field.setAccessible(true);

                String columnName = getColumnName(field);
                sql.append(columnName).append(",");

            }
            sql.deleteCharAt(sql.length() - 1);
            sql.append(") VALUES (");

            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                field.setAccessible(true);
                try {
                    Object value = field.get(entity);

                    if (field.isAnnotationPresent(TableId.class)) {
                        int randomNumber;
                        synchronized (this) {
                            Random random = new Random();
                            randomNumber = random.nextInt(100000);
                        }
                        sql.append("'").append(System.currentTimeMillis() + randomNumber).append("',");
                    } else if (value == null) {
                        sql.append("").append(value).append(",");
                    } else {
                        sql.append("'").append(value).append("',");
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            sql.deleteCharAt(sql.length() - 1);
            sql.append(")");

            return sql.toString();
        }

        public String update(T entity) throws Exception {
            Class<?> clazz = entity.getClass();
            StringBuilder sql = new StringBuilder();
            sql.append("UPDATE ").append(getTableName(clazz)).append(" SET ");

            Field[] fields = clazz.getDeclaredFields();
            String idColumn = "id";
            Object idValue = null;
            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                field.setAccessible(true);
                String columnName = getColumnName(field);
                sql.append(columnName).append("=");

                try {
                    if (field.isAnnotationPresent(TableId.class)) {
                        idColumn = getColumnName(field);
                        idValue = field.get(entity);
                    }
                    Object value = field.get(entity);
                    if (value == null) {
                        sql.append("").append(value).append(",");
                    } else {
                        sql.append("'").append(value).append("',");
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
            sql.deleteCharAt(sql.length() - 1);
            sql.append(" WHERE ").append(idColumn).append(" = ").append(idValue);

            return sql.toString();
        }

        public String deleteById(T entity) throws Exception {
            Class<?> clazz = entity.getClass();
            Field[] fields = clazz.getDeclaredFields();
            String idColumn = "id"; // 假设ID列名为"id"
            Object idValue = null;
            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                field.setAccessible(true);

                if (field.isAnnotationPresent(TableId.class)) {
                    idColumn = getColumnName(field);
                    idValue = field.get(entity);
                }
            }
            String sql = "DELETE FROM " + getTableName(clazz) + " WHERE " + idColumn + "=" + idValue;
            return sql.toString();
        }

        public String getById2(T entity) throws Exception {
            Class<?> clazz = entity.getClass();
            StringBuilder sql = new StringBuilder();
            Field[] fields = clazz.getDeclaredFields();
            String idColumn = "id"; // 假设ID列名为"id"
            Object idValue = null;
            sql.append("SELECT ");
            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                field.setAccessible(true);

                String columnName = getColumnName(field);
                sql.append(columnName).append(",");
                if (field.isAnnotationPresent(TableId.class)) {
                    idColumn = getColumnName(field);
                    idValue = field.get(entity);
                }
            }
            sql.deleteCharAt(sql.length() - 1);

            sql.append(" FROM ").append(getTableName(clazz))
                    .append(" WHERE ")
                    .append(idColumn + "=" + idValue);
            return sql.toString();
        }

        public String getById(T entity) throws Exception {
            Class<?> clazz = entity.getClass();
            String idColumn = "id"; // 假设ID列名为"id"
            Field[] fields = clazz.getDeclaredFields();
            Object idValue = null;
            for (int i = 0; i < fields.length; i++) {
                Field field = fields[i];
                field.setAccessible(true);

                if (field.isAnnotationPresent(TableId.class)) {
                    idColumn = getColumnName(field);
                    idValue = field.get(entity);
                }
            }
            String sql = "SELECT *  FROM " + getTableName(clazz) + " WHERE " + idColumn + "=" + idValue;
            return sql;
        }


        // 根据实体类获取表名
        public String getTableName(Class<?> clazz) {
            String className = clazz.getSimpleName();
            StringBuilder tableName = new StringBuilder();
            boolean isFirstCharacter = true; // 判断是否为类名首字母

            for (int i = 0; i < className.length(); i++) {
                char ch = className.charAt(i);

                if (isFirstCharacter) {
                    tableName.append(Character.toLowerCase(ch));
                    isFirstCharacter = false;
                } else {
                    if (Character.isUpperCase(ch)) {
                        tableName.append("_");
                    }
                    tableName.append(Character.toLowerCase(ch));
                }
            }

            return tableName.toString();
        }

        // 根据字段获取列名
        public String getColumnName(Field field) {
            String fieldName = field.getName();
            StringBuilder columnName = new StringBuilder();
            for (int i = 0; i < fieldName.length(); i++) {
                char ch = fieldName.charAt(i);
                if (Character.isUpperCase(ch)) {
                    columnName.append("_");
                }
                columnName.append(Character.toLowerCase(ch));
            }
            return columnName.toString();
        }

    }
}